package controllers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import models.BaseEntity.PeopleType;
import models.BaseEntity.Status;
import models.Commodity;
import models.Commodity.OnSaleStatus;
import models.Order.OrderStatus;
import models.Order;
import models.OrderItem;
import models.QueryBean;
import models.RemittanceConfirm;
import models.ShoppingCar;
import models.TransferPrice;
import models.User;
import play.data.validation.Valid;
import play.db.jpa.JPA;
import play.mvc.Controller;
import play.mvc.With;
import service.CommoditiesService;
import service.OrderService;

@With(Secure.class)
public class Orders extends Controller {
	
	/**
	 * 订单详细信息。
	 * @param orderId
	 */
	public static void orderDetail(long id) {
		Order order = Order.findById(id);
		order.orderItems = OrderItem.find("order.id = ?", id).fetch();
		render("@Users.orderDetail", order);
	}
	
	/**
	 * 新建订单。
	 * @param order
	 */
	public static void saveNewOrder(@Valid Order order) {
		if(validation.hasErrors()) {
			params.flash(); // add http parameters to the flash scope
			validation.keep(); // keep the errors for the next request
			render("@Users.newOrder", order);
		}
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		order.user = user;
		
		TransferPrice tp = TransferPrice.findById(order.transferPrice.id);
		order.baseFreightKG = tp.privateBaseWeight;
		order.baseFreight = tp.privateBasePrice;
		order.freightPerKG = tp.privateRenewalPrice;
		
		List<ShoppingCar> shoppingCars = ShoppingCar.find("user.id=?", user.id).fetch();
		order.orderItems = OrderService.convert2OrderItems(shoppingCars, order , user);
		if(order.orderItems == null || order.orderItems.size() < 1) {
			String errMsg = "订单生成失败，购物车中没有商品。";
			QueryBean queryBean = new QueryBean();
			render("@Users.shoppingCar" , errMsg, queryBean);
		}
		
		OrderService.create(order, user);
		ShoppingCar.delete("user.id=?", user.id);
		Orders.orderDetail(order.id);
	}
	
	/**
	 * 计算各项费用并跳转到新建订单页面。
	 */
	public static void newOrder() {
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		//初始化数据。
		Order order = new Order();
		order.receiver = user.realname;
		order.deliveryAddress = user.deliveryAddress;
		order.zipCode = user.zipcode;
		order.phoneNo = user.phoneNo;
		order.email = user.email;
		order.orderingType = Order.ORDERTYPE_SELF;
		
		List<ShoppingCar> shoppingCars = ShoppingCar.find("user.id=?", user.id).fetch();
		order.orderItems = OrderService.convert2OrderItems(shoppingCars, order, user);
		if(order.orderItems == null || order.orderItems.size() < 1) {
			String errMsg = "订单生成失败，购物车中没有商品。";
			QueryBean queryBean = new QueryBean();
			render("@Users.shoppingCar" , errMsg, queryBean);
		}
		OrderService.caculateOrder(order);
		render("@Users.newOrder", order);
	}
	
	/**
	 * 汇款确认申请页面。
	 * @param id
	 */
	public static void remittanceConfirm(long id) {
		Order order = Order.findById(id);
		RemittanceConfirm remittanceConfirm = new RemittanceConfirm();
		remittanceConfirm.payType = RemittanceConfirm.PAYTYPE_ONLINE;
		remittanceConfirm.order = order;
		remittanceConfirm.paierName = order.user.username;
		remittanceConfirm.phone = order.user.phoneNo;
		remittanceConfirm.address = order.user.deliveryAddress;
		remittanceConfirm.email = order.user.email;
		remittanceConfirm.price = order.totalPrice;
		render("@Users.remittanceConfirm", remittanceConfirm);
	}
	
	/**
	 * 提交汇款确认申请单。
	 * @param order
	 */
	public static void submitRemittanceConfirm(@Valid RemittanceConfirm remittanceConfirm) {
		if(validation.hasErrors()) {
			params.flash(); // add http parameters to the flash scope
//			validation.keep(); // keep the errors for the next request
			render("@Users.remittanceConfirm", remittanceConfirm);
		}
		
		Order order = Order.findById(remittanceConfirm.order.id);
		if(!OrderStatus.NEW.equals(order.orderStatus)) {
			validation.addError("errMsg.status", "确认出错，订单状态必须是新订单才能发送确认。");
			params.flash(); // add http parameters to the flash scope
			render("@Users.remittanceConfirm", remittanceConfirm);
		}
		order.orderStatus = OrderStatus.PAID;
		order.resetModifier(order.user);
		order.save();
		
		remittanceConfirm.order = order;
		remittanceConfirm.setCreator(order.user);
		remittanceConfirm.resetModifier(order.user);
		remittanceConfirm.confirmStatus = RemittanceConfirm.ConfirmStatus.NEW;
		remittanceConfirm.save();
		
		orderDetail(order.id);
	}
	
	/**
	 * 修改订单项页面。
	 */
	public static void editOrderItems(long id) {
		Order order = Order.findById(id);
		order.orderItems =  OrderItem.find("order.id = ?", id).fetch();
		render("@Users.editOrderItems", order);
	}
	
	/**
	 * 删除订单项。
	 * @param id
	 * @throws Exception 
	 */
	public static void removeOrderItem(long id) throws Exception {
		OrderItem orderItem = OrderItem.findById(id);
		if(orderItem == null || orderItem.order == null 
				|| OrderStatus.NEW != orderItem.order.orderStatus) {
			throw new Exception("订单（"+orderItem.order.id+"）不是新订单，不能进行修改。");
		}
		OrderItem.delete("id=?", id);
	}
	/**
	 * 删除订单。
	 * @param id
	 * @throws Exception
	 */
	public static void removeOrder(long id) throws Exception {
		Order order = Order.findById(id);
		if(order == null || OrderStatus.NEW != order.orderStatus) {
			throw new Exception("订单（"+id+"）不是新订单，不能进行修改。");
		}
		OrderService.delete(order);
	}
	/**
	 * 保存用户修改项。
	 * @param id
	 * @throws Exception
	 */
	public static void saveOrderItems(long orderId) throws Exception {
		Order order = Order.findById(orderId);
		if(order == null || OrderStatus.NEW != order.orderStatus) {
			throw new Exception("订单（"+orderId+"）不是新订单，不能进行修改。");
		}
		List<OrderItem> orderItems = obtainOrderItem();
		for(OrderItem item : orderItems) {
			if(item.quantity > item.commodity.quantityLeft) {
				throw new Exception("商品（"+item.commodity.name+"）库存不足，请修改购买数量。");
			}
		}
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		for(OrderItem item : orderItems) {
			item.resetModifier(user);
			item.save();
		}
		order.orderItems = orderItems;
		OrderService.caculateOrder(order);
		order.save();
	}
	
	private static List<OrderItem> obtainOrderItem() throws Exception {
		List<OrderItem> items = new ArrayList<OrderItem>();
		int i = 0;
		while (true) {
			String idStr = request.params.get("orders[" + i + "].id");
			if(ValidationUtil.isEmpty(idStr)) break;
			long id = Long.valueOf(idStr);
			String quantity = request.params.get("orders[" + i + "].quantity");
			if(!ValidationUtil.isLong(quantity)){
				String errMsg = "购买数量必须为数字。";
				throw new Exception(errMsg);
			}
			OrderItem item = OrderItem.findById(id);
			if(item == null) {
				String errMsg = "订单项（"+ id +"）已经被移出购物车。";
				throw new Exception(errMsg);
			}
			item.quantity = Long.valueOf(quantity);
			item.remark = request.params.get("orders[" + i + "].remark");
			item.lastModifiedAt = new Date();
			items.add(item);
			i++;
		}
		return items;
	}
	
	/**
	 * 修改OrderDetail页面。
	 * @throws Exception
	 */
	public static void editOrderDetail(long id) throws Exception {
		Order order = Order.findById(id);
		render("@Users.editOrderDetail", order);
	}
	
	/**
	 * 保存
	 * @param order
	 * @throws Exception
	 */
	public static void confirmOrderInfo(@Valid Order order) throws Exception {
		if(validation.hasErrors()) {
			params.flash(); // add http parameters to the flash scope
			validation.keep(); // keep the errors for the next request
			render("@Users.editOrderDetail", order);
		}
		
		Order oriOrder = Order.findById(order.id);
		
		TransferPrice tp = TransferPrice.findById(order.transferPrice.id);
		order.baseFreightKG = tp.privateBaseWeight;
		order.baseFreight = tp.privateBasePrice;
		order.freightPerKG = tp.privateRenewalPrice;
		
		order.user = oriOrder.user;
		order.orderItems = OrderItem.find("order.id", order.id).fetch();
		OrderService.caculateOrder(order);
		render("@Users.confirmOrderInfo", order);
	}
	
	public static void saveOrder(Order order) {
		Order oriOrder = Order.findById(order.id);
		
		TransferPrice tp = TransferPrice.findById(order.transferPrice.id);
		oriOrder.baseFreightKG = tp.privateBaseWeight;
		oriOrder.baseFreight = tp.privateBasePrice;
		oriOrder.freightPerKG = tp.privateRenewalPrice;
		
		oriOrder.receiver = order.receiver;
		oriOrder.phoneNo = order.phoneNo;
		oriOrder.email = order.email;
		oriOrder.zipCode = order.zipCode;
		oriOrder.deliveryAddress = order.deliveryAddress;
		oriOrder.arrivalTime = order.arrivalTime;
		oriOrder.orderTransportCompany = order.orderTransportCompany;
		oriOrder.orderingType = order.orderingType;
		oriOrder.remark = order.remark;
		
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		oriOrder.resetModifier(user);
		
		oriOrder.orderItems = OrderItem.find("order.id", order.id).fetch();
		OrderService.caculateOrder(order);
		order.save();
		orderDetail(order.id);
	}
	
	/**
	 * 合并订单。
	 * @param idA 订单A的ID
	 * @param idB 订单B的ID
	 * @throws Exception 
	 */
	public static void megerOrders(long idA, long idB) throws Exception {
		Order orderA = Order.findById(idA);
		Order orderB = Order.findById(idB);
		if(orderA == null || OrderStatus.NEW != orderA.orderStatus) {
			validation.addError("errMsg", "订单("+idA+")不是新订单");
		}
		if(orderB == null || OrderStatus.NEW != orderB.orderStatus) {
			validation.addError("errMsg", "订单("+idB+")不是新订单");
		}
		if(validation.hasErrors()) {
			params.flash(); // add http parameters to the flash scope
			validation.keep(); // keep the errors for the next request
			Users.order(null);
		}
		
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		//初始化数据。
		Order order = new Order();
		order.receiver = user.realname;
		order.deliveryAddress = user.deliveryAddress;
		order.zipCode = user.zipcode;
		order.phoneNo = user.phoneNo;
		order.email = user.email;
		order.orderingType = Order.ORDERTYPE_SELF;
		
		order.orderItems = new ArrayList<OrderItem>();
		orderA.orderItems = OrderItem.find("order.id=?", orderA.id).fetch();
		orderB.orderItems = OrderItem.find("order.id=?", orderB.id).fetch();
		order.orderItems.addAll(orderA.orderItems);
		order.orderItems.addAll(orderB.orderItems);
		OrderService.caculateOrder(order);
		render("@users.megerOrders", order, orderA, orderB);
	}
	
	/**
	 * 却订提交订单。
	 * @param order 用户输入参数。
	 * @param orderA 订单1
	 * @param orderB 订单2
	 * @throws Exception 
	 */
	public static void sure2MegerOrders(Order order, Order orderA, Order orderB) throws Exception {
		orderA = Order.findById(orderA.id);
		orderB = Order.findById(orderB.id);
		if(orderA == null || OrderStatus.NEW != orderA.orderStatus) {
			validation.addError("errMsg", "订单("+orderA.id+")不是新订单");
		}
		if(orderB == null || OrderStatus.NEW != orderB.orderStatus) {
			validation.addError("errMsg", "订单("+orderB.id+")不是新订单");
		}
		if(validation.hasErrors()) {
			params.flash(); // add http parameters to the flash scope
			validation.keep(); // keep the errors for the next request
			Users.order(null);
		}
		
		TransferPrice tp = TransferPrice.findById(order.transferPrice.id);
		order.baseFreightKG = tp.privateBaseWeight;
		order.baseFreight = tp.privateBasePrice;
		order.freightPerKG = tp.privateRenewalPrice;
		
		String username = session.get(GlobalVariables.SECURE_USERNAME);
		User user = User.find("byUsername", username).first();
		
		order.orderItems = new ArrayList<OrderItem>();
		
		order.user = user;
		
		
		List<OrderItem> itemsA = OrderItem.find("order.id=?", orderA.id).fetch();
		List<OrderItem> itemsB = OrderItem.find("order.id=?", orderB.id).fetch();
		
		if(itemsA != null){
			for(OrderItem item : itemsA) {
				OrderItem i = item.clone();
				i.order = order;
				order.orderItems.add(i);
			}
		}
		
		if(itemsB != null){
			for(OrderItem item : itemsB) {
				OrderItem duplicateItem = null;
				for(OrderItem existItem : order.orderItems) {
					if(existItem.commodity.id == item.commodity.id) {
						duplicateItem = existItem;
						break;
					}
				}
				if(duplicateItem == null) {
					OrderItem i = item.clone();
					i.order = order;
					order.orderItems.add(i);
				} else {
					duplicateItem.quantity += item.quantity;
					if((duplicateItem.remark == null || duplicateItem.remark.trim() == "")
						&& item.remark != null && item.remark.trim() != "") {
						duplicateItem.remark = item.remark;
					} else {
						duplicateItem.remark = duplicateItem.remark + "\t" +item.remark;
					}
				}
			}
		}
		OrderService.create(order, user);
		JPA.em().flush();
		orderA.delete();
		orderB.delete();
		Users.order(null);
	}
}